package org.example.socket.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class NioTcpClient {
    private static final ExecutorService executor = Executors.newFixedThreadPool(10);
    private static final int LOOP_TIMES = 5000;
    private final InetSocketAddress inetSocketAddress;

    public NioTcpClient(String hostname, int port) {
        inetSocketAddress = new InetSocketAddress(hostname, port);
    }

    public void send(String requestData) {
        try {
            SocketChannel socketChannel = SocketChannel.open(inetSocketAddress);
            socketChannel.configureBlocking(false);
            ByteBuffer byteBuffer = ByteBuffer.allocate(512);
            socketChannel.write(ByteBuffer.wrap(requestData.getBytes()));
            while (true) {
                byteBuffer.clear();
                int readBytes = socketChannel.read(byteBuffer);
                if (readBytes > 0) {
                    byteBuffer.flip();
                    System.out.println("Client: readBytes = " + readBytes);
                    System.out.println("Client: data = " + new String(byteBuffer.array(), 0, readBytes));
                    socketChannel.close();
                    break;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws InterruptedException {

        NioTcpClient client = new NioTcpClient("localhost", 10000);
        long startT = System.currentTimeMillis();
        CountDownLatch countDownLatch = new CountDownLatch(LOOP_TIMES);
        for (int i = 0; i < LOOP_TIMES; i++) {
            executor.execute(() -> {
                client.send("hello server");
                countDownLatch.countDown();
            });
        }
        countDownLatch.await();
        System.out.println("total cost:" + (System.currentTimeMillis() - startT) + " ms.");
        executor.shutdown();
    }
}